package com.phone.rest.modular.auth.filter;

import com.phone.rest.common.exception.BizExceptionEnum;
import com.phone.rest.config.properties.JwtProperties;
import com.phone.rest.config.properties.WxProperties;
import com.phone.rest.modular.auth.util.JwtTokenUtil;
import com.phone.core.base.tips.ErrorTip;
import com.phone.core.util.RenderUtil;
import io.jsonwebtoken.JwtException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 对客户端请求的jwt token验证过滤器
 *
 * @author zengzr
 * @Date 2017/8/24 14:04
 */
public class AuthFilter extends OncePerRequestFilter {

    private final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private WxProperties wxProperties;

    private List<String> unFilterUrl = new ArrayList<String>();

    {
        //注意以/开头注册
        unFilterUrl.add("/backend");
        unFilterUrl.add("/api");
    }

    private Boolean validateUri(String contPath, String uri){
        uri = uri.replaceAll("/", "").replaceAll("\\\\", "");
        for(String unFilterUri : unFilterUrl){
            unFilterUri = contPath+unFilterUri;
            unFilterUri = unFilterUri.replaceAll("/", "").replaceAll("\\\\", "");
            if(uri.startsWith(unFilterUri)) return true;
        }
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String contPath=request.getContextPath();
        String uri = request.getRequestURI();
        uri = uri.replaceAll("/", "").replaceAll("\\\\", "");
        if (validateUri(contPath,uri) ) {
            chain.doFilter(request, response);
            return;
        }
        final String requestHeader = request.getHeader(jwtProperties.getHeader());
        String authToken = null;
        if (requestHeader != null && requestHeader.startsWith("token=")) {
            authToken = requestHeader.substring(6);
            //验证token是否过期
            try {
                boolean flag = jwtTokenUtil.isTokenExpired(authToken);
                if (flag) {
                    RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_EXPIRED.getCode(), BizExceptionEnum.TOKEN_EXPIRED.getMessage()));
                    return;
                }
            } catch (JwtException e) {
                //有异常就是token解析失败
                RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
                return;
            }
        } else {
            //header没有带Bearer字段
            RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
            return;
        }
        chain.doFilter(request, response);
    }

    public List<String> getUnFilterUrl() {
        return unFilterUrl;
    }

    public void setUnFilterUrl(List<String> unFilterUrl) {
        this.unFilterUrl = unFilterUrl;
    }
}